import * as Tone from 'tone';

class AudioAnalyzerService {
  constructor() {
    this.player = null;
    this.analyzer = null;
    this.isPlaying = false;
    this.onBeatCallbacks = [];
    this.noteData = [];
    this.currentTime = 0;
    this._startTime = null;
  }

  async initialize() {
    try {
      console.log('初始化Tone.js音频引擎...');
      await Tone.start();
      console.log('Tone.js音频引擎启动成功');
      
      if (!this.player) {
        this.player = new Tone.Player().toDestination();
        console.log('创建Tone.Player成功');
        
        // 创建分析器
        this.analyzer = new Tone.Analyser('waveform', 1024);
        this.fft = new Tone.FFT(1024);
        this.meter = new Tone.Meter();
        console.log('创建音频分析器成功');
        
        // 连接分析器
        this.player.connect(this.analyzer);
        this.player.connect(this.fft);
        this.player.connect(this.meter);
        console.log('连接音频分析器成功');
        
        // 创建一个循环来检测节拍
        Tone.Transport.scheduleRepeat((time) => {
          this.detectBeats(time);
        }, '16n');
        
        Tone.Transport.bpm.value = 120;
        console.log('设置Transport完成');
      }
    } catch (error) {
      console.error('初始化Tone.js失败:', error);
    }
  }

  async loadSong(url) {
    try {
      console.log('开始加载音频文件:', url);
      
      // 停止当前播放
      this.stop();
      this.noteData = [];
      
      // 生成默认音符数据
      this.generateDefaultNoteData();
      console.log('生成默认音符数据完成，数量:', this.noteData.length);
      
      // 加载音频文件
      if (this.player) {
        try {
          await this.player.load(url);
          console.log('音频文件加载成功');
          
          // 分析音频生成音符数据
          await this.analyzeFullSong();
          console.log('音频分析完成，音符数量:', this.noteData.length);
        } catch (audioError) {
          console.warn('音频加载或分析失败，将使用默认节奏:', audioError);
        }
      } else {
        console.warn('播放器未初始化，将使用默认节奏');
      }
      
      return this.noteData;
    } catch (error) {
      console.error('加载歌曲完全失败:', error);
      if (this.noteData.length === 0) {
        this.generateDefaultNoteData();
      }
      return this.noteData;
    }
  }

  play() {
    try {
      console.log('开始播放音频...');
      
      // 重置时间
      this.currentTime = 0;
      this._startTime = Date.now() / 1000;
      
      // 确保Tone.js已经初始化
      if (Tone.context.state !== 'running') {
        console.log('正在启动Tone.js上下文...');
        Tone.start();
      }
      
      // 启动音频播放
      if (this.player) {
        try {
          if (this.player.loaded) {
            this.player.start();
            console.log('音频开始播放');
          } else {
            console.warn('音频尚未加载完成');
          }
        } catch (e) {
          console.warn('音频播放失败，但游戏将继续:', e);
        }
      } else {
        console.warn('播放器未初始化');
      }
      
      // 启动Transport
      try {
        Tone.Transport.start();
        console.log('Transport已启动');
      } catch (e) {
        console.warn('Transport启动失败:', e);
      }
      
      this.isPlaying = true;
      
      // 更新当前播放时间
      if (this.timeInterval) {
        clearInterval(this.timeInterval);
      }
      
      this.timeInterval = setInterval(() => {
        if (this.player && this.player.loaded) {
          this.currentTime = this.player.currentTime;
        } else {
          this.currentTime = (Date.now() / 1000) - this._startTime;
        }
      }, 16);
      
      console.log('游戏开始播放，当前时间:', this.currentTime);
    } catch (error) {
      console.error('播放出错但会继续游戏:', error);
      this.isPlaying = true;
      
      // 使用系统时间作为备用
      this._startTime = Date.now() / 1000;
      this.timeInterval = setInterval(() => {
        this.currentTime = (Date.now() / 1000) - this._startTime;
      }, 16);
    }
  }

  stop() {
    console.log('停止游戏播放');
    
    try {
      if (this.player) {
        try {
          this.player.stop();
        } catch (e) {
          console.warn('停止音频播放失败:', e);
        }
      }
      
      Tone.Transport.stop();
    } catch (e) {
      console.warn('停止Transport失败:', e);
    }
    
    this.isPlaying = false;
    
    if (this.timeInterval) {
      clearInterval(this.timeInterval);
    }
    
    this.currentTime = 0;
    this._startTime = null;
  }

  // 分析整首歌曲并提前生成音符数据
  async analyzeFullSong() {
    // 这里是一个简化版的分析过程，实际应用中可能需要更复杂的算法
    // 例如使用Meyda或其他库进行更详细的音频特征提取
    
    const duration = this.player.buffer.duration;
    const bpm = 120; // 可以使用BPM检测算法来自动获取
    
    // 根据BPM计算每拍的时间
    const beatTime = 60 / bpm;
    
    // 根据BPM生成音符数据（简化版）
    let currentBeat = 0;
    
    while (currentBeat * beatTime < duration) {
      // 随机生成四种按键类型 (q, w, e, r)
      const keyType = ['q', 'w', 'e', 'r'][Math.floor(Math.random() * 4)];
      
      // 一定概率生成长音符 (空格键)
      const isLongNote = Math.random() > 0.8;
      const noteKey = isLongNote ? 'space' : keyType;
      
      // 长音符的持续时间
      const noteDuration = isLongNote ? beatTime * 2 : beatTime / 2;
      
      // 音符位置和轨道
      const lane = ['q', 'w', 'e', 'r'].indexOf(keyType);
      
      // 生成音符数据
      this.noteData.push({
        time: currentBeat * beatTime,
        duration: noteDuration,
        key: noteKey,
        lane: lane >= 0 ? lane : 0, // 如果是空格键，放在第一个轨道
        isLongNote: isLongNote
      });
      
      // 下一拍（有时候跳过一拍来创造节奏变化）
      currentBeat += Math.random() > 0.3 ? 1 : 2;
    }
    
    return this.noteData;
  }

  // 实时检测节拍
  detectBeats(time) {
    if (!this.isPlaying || !this.meter) return;
    
    const level = this.meter.getValue();
    const threshold = -30; // 分贝阈值，可以根据音乐类型调整
    
    if (level > threshold) {
      this.onBeatCallbacks.forEach(callback => callback(time, level));
    }
  }

  // 订阅节拍事件
  onBeat(callback) {
    this.onBeatCallbacks.push(callback);
    return () => {
      this.onBeatCallbacks = this.onBeatCallbacks.filter(cb => cb !== callback);
    };
  }

  // 获取当前活跃的音符
  getActiveNotes(timeWindow = 3) {
    const currentTime = this.currentTime;
    return this.noteData.filter(note => {
      return note.time >= currentTime && note.time <= currentTime + timeWindow;
    });
  }

  // 生成默认音符数据，当加载失败时使用
  generateDefaultNoteData() {
    console.log('生成默认音符数据');
    const duration = 60; // 默认1分钟的音符数据
    const bpm = 120;
    const beatTime = 60 / bpm;
    
    // 根据BPM生成音符数据（简化版）
    let currentBeat = 0;
    
    while (currentBeat * beatTime < duration) {
      // 随机生成四种按键类型 (q, w, e, r)
      const keyType = ['q', 'w', 'e', 'r'][Math.floor(Math.random() * 4)];
      
      // 一定概率生成长音符 (空格键)
      const isLongNote = Math.random() > 0.8;
      const noteKey = isLongNote ? 'space' : keyType;
      
      // 长音符的持续时间
      const noteDuration = isLongNote ? beatTime * 2 : beatTime / 2;
      
      // 音符位置和轨道
      const lane = ['q', 'w', 'e', 'r'].indexOf(keyType);
      
      // 生成音符数据
      this.noteData.push({
        time: currentBeat * beatTime,
        duration: noteDuration,
        key: noteKey,
        lane: lane >= 0 ? lane : 0, // 如果是空格键，放在第一个轨道
        isLongNote: isLongNote
      });
      
      // 下一拍（有时候跳过一拍来创造节奏变化）
      currentBeat += Math.random() > 0.3 ? 1 : 2;
    }
    
    return this.noteData;
  }
}

// 创建单例
const audioAnalyzerService = new AudioAnalyzerService();
export default audioAnalyzerService; 